<?php
/**
 * @author spenceryg
 * @date 2022/11/21
 * @time 10:44 上午
 * @focus love & life
 */


namespace app\common\lib;


use app\common\lib\translate\Translate;
use ShaoZeMing\Translate\Exceptions\TranslateException;
use ShaoZeMing\Translate\TranslateService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;

class SpTranslate
{
    private static $config = [
        'defaults' => [
            'driver' => 'google',   //默认使用google翻译
            'spare_driver' => 'baidu',  // 备用翻译api ,第一个翻译失败情况下，调用备用翻译服务，填写备用翻译api 需要在下面对应的drivers中配置你参数
            'from' => 'zh',   //原文本语言类型 ，目前支持：auto【自动检测】,en【英语】,zh【中文】，jp【日语】,ko【韩语】，fr【法语】，ru【俄文】，pt【西班牙】
            'to' => 'en',     //翻译文本 ：en【英语】,zh【中文】，jp【日语】,ko【韩语】，fr【法语】，ru【俄文】，pt【西班牙】,
        ],

        'drivers' => [
            'baidu' => [
                'base_url' => 'http://api.fanyi.baidu.com/api/trans/vip/translate',
                //App id of the translation api
                'app_id' => '20221121001462606',
                //secret of the translation api
                'app_key' => 'FVwTqx5sgxmMmN2qNP79',
            ],

            'youdao' => [
                'base_url' => 'https://openapi.youdao.com/api',
                //App id of the translation api
                'app_id' => '',
                //secret of the translation api
                'app_key' => '',
            ],

            'google' => [
                'base_url' => 'http://translate.google.cn/translate_a/single',
                'app_id' => '',
                'app_key' => '',
            ],
        ],
    ];

    /**
     * getChinese
     * @param $word
     * @return mixed
     * @throws TranslateException
     */
    public static function getChinese($word)
    {
        // 查询本地
        $res = self::getLocalTranslate($word);
        if ($res) {
            return $res;
        }
        // 查询网络
        $obj = new TranslateService(self::$config);
        $from = 'en';
        $to = 'zh';
        $res = $obj->setDriver('baidu')->setFromAndTo($from,$to)->translate($word);
        // 保存查询到本地
        Translate::create([
            'from' => $word,
            'to' => $res
        ]);
        return $res;
    }


    /**
     * getEnglish
     * @param $word
     * @return mixed
     * @throws TranslateException
     */
    public static function getEnglish($word)
    {
        [$prefix, $realWord, $suffix] = self::getRealWord($word);
        // 查询本地
        $res = self::getLocalTranslate($realWord);
        if ($res) {
            return $prefix . $res . $suffix;
        }
        // 查询网络
        $obj = new TranslateService(self::$config);
        $from = 'zh';
        $to = 'en';
        $res = $obj->setDriver('baidu')->setFromAndTo($from,$to)->translate($realWord);
        $res = str_replace('_ ','_', $res);
        $res = str_replace(' ','_', $res);
        $res = strtolower($res);
        $real_word_type = self::getFieldType($realWord);
        // 保存查询到本地
        Translate::create([
            'from' => $realWord,
            'to' => $res,
            'type' => self::getFieldType($real_word_type),
        ]);
        return $prefix . $res . $suffix;
    }


    /**
     * 获取英文翻译 + 字段类型
     * getEnglishWithType
     * @param $word
     * @return array
     * @throws TranslateException
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getEnglishWithType($word): array
    {
        [$prefix, $realWord, $suffix] = self::getRealWord($word);
        // 查询本地
        $res = self::getLocalTranslateWithType($realWord);
        if ($res) {
            return [
                'res' =>  $prefix . $res['to'] . $suffix,
                'type' => $prefix || $suffix ? self::getFieldType($word) :$res['type']
                ];
        }
        // 查询网络
        [$prefix, $realWord, $suffix] = self::getRealWord($word);
        $obj = new TranslateService(self::$config);
        $from = 'zh';
        $to = 'en';
        $res = $obj->setDriver('baidu')->setFromAndTo($from,$to)->translate($realWord);
        $res = str_replace('_ ','_', $res);
        $res = str_replace(' ','_', $res);
        $res = strtolower($res);
        $real_word_type = self::getFieldType($realWord);
        // 保存查询到本地
        Translate::create([
            'from' => $realWord,
            'to' => $res,
            'type' => $real_word_type,
        ]);

        return [
            'res' =>$prefix. $res .$suffix,
            'type' => self::getFieldType($word)
        ];
    }




    /**
     * 获取本地翻译
     * getLocalTranslate
     * @param $word
     * @return mixed
     */
    private static function getLocalTranslate($word)
    {
        return Translate::where('from', $word)->value('to');
    }


    /**
     * 获取本地翻译带类型
     * getLocalTranslate
     * @param $word
     * @return mixed
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function getLocalTranslateWithType($word)
    {
        return Translate::where('from', $word)->find();
    }


    /**
     * 获取翻译结果的默认字段类型
     * getFieldType
     * @param $word
     * @return string
     */
    private static function getFieldType($word): string
    {
        $return_type = 'varchar';

        $type_conditions = [
            'int'=> [
                '排序',
                '排名',
                '数量',
                '人数',
                '个数',
                '年龄',
                '年纪',
                '排名',
                '名次',
                '日期',
                '时间',
            ],
            'double' => [
                '金钱',
                '价格',
            ],
            'tinyint' => [
                '是否',
                '性别'
            ],
            'text' => [
                '简介',
                '介绍',
                '相册',
                '图集',
                '多图',
            ],
            'longtext' => [
                '内容',
                '详情'
            ]
        ];

        foreach ($type_conditions as $type => $conditions) {
            foreach ($conditions as $needle ) {
                if(strpos($word, $needle)!==false) {
                    $return_type =  $type;
                }
            }
        }
        return $return_type;
    }


    /**
     * getRealWord
     * @param $word
     * @return array
     */
    private static function getRealWord($word): array
    {
        $prefix = '';
        $realWord = $word;
        $suffix = '';
        if(strpos($word,'是否' )===0) {
            $prefix = 'is_';
            $realWord = str_replace('是否', '', $word);
        }
        return [
            $prefix, $realWord, $suffix
        ];
    }
}
